package msi.gama.display.java3d.renderingObject;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Group;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3f;

import msi.gama.metamodel.shape.IShape;

/**
 * minhvv, p18, IFI, TPE 01/2014 - 07/2014
 */

public class RenderingObject {
	private BranchGroup branchGroup = null;
	private TransformGroup tranformGroup = null;

	private VisualObject visualObj = null;
	private InfoObject infoObj = null;

	private String objId = "";
	private boolean isDead = false;

	public RenderingObject(String objId, Vector3f position,
			IShape geometry, Color3f color, Color3f borderColor,
			boolean isFilled, boolean isRounded) {

		this.objId = objId;
		this.isDead = false;

		createScene();
		setSceneCapacities();

		createRenderingObject(position, geometry, color, borderColor, isFilled, isRounded);
		addRenderingObjectToScene();

		selfMove(true);
	}

	private void createScene() {
		branchGroup = new BranchGroup();
		branchGroup.setUserData(this);

		tranformGroup = new TransformGroup();
		branchGroup.addChild(tranformGroup);
	}

	private void setSceneCapacities() {
		branchGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
		branchGroup.setCapability(BranchGroup.ALLOW_DETACH);

		tranformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tranformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
	}

	private void createRenderingObject(Vector3f position, IShape geometry,
			Color3f color, Color3f borderColor,
			boolean isFilled, boolean isRounded) {
		visualObj = new VisualObject(geometry, color, borderColor, isFilled, isRounded);
		infoObj = new InfoObject(position);
	}

	private void addRenderingObjectToScene() {
		tranformGroup.addChild(visualObj.getPrimitiveShape());
	}

	private void selfMove(boolean isForced) {
		if (true == isForced || infoObj.isPositionChanged()) {
			Vector3f newPosition = infoObj.getCurrentPosition();
			_moveTo(newPosition);
		}
	}

	private void _moveTo(Vector3f newPos) {
		Transform3D tran = new Transform3D();
		tran.setTranslation(newPos);
		tranformGroup.setTransform(tran);
	}

	/*
	 * FOR UPDATE DATA
	 */

	public void updateDataOnEachFrame(String objId, Vector3f position,
			IShape geometry, Color3f color, Color3f borderColor,
			boolean isFilled, boolean isRounded) {

		if (!this.objId.equals(objId)) {
			return;
		}

		visualObj.setNewData(geometry, color, borderColor, isFilled, isRounded);
		infoObj.setNewData(position);

		selfMove(false);
	}

	/*
	 * API FOR PUBLIC CALL
	 */

	public BranchGroup getScene() {
		branchGroup.compile();
		return branchGroup;
	}

	public boolean isMatch(String otherId) {
		return this.objId.equals(otherId);
	}

	public void setObjectDead() {
		this.isDead = true;
	}

	public boolean isObjectDead() {
		return true == isDead;
	}

	/*
	 * FOR DEBUG
	 */
	public String toString() {
		return "id: " + this.objId + ", isDead: " + isDead
				+ visualObj.toString() + "\t" + infoObj.toString();
	}
}
